package com.xsqf.jt808.netty.handler;

import com.xsqf.jt808.common.config.ChannelManager;
import com.xsqf.jt808.common.util.BitOperator;
import com.xsqf.jt808.common.vo.VehicleTerminalVo;
import com.xsqf.jt808.common.vo.req.terminal.LocationMsg;
import com.xsqf.jt808.common.vo.resp.CommonResp;
import com.xsqf.jt808.entity.LocationRecord;
import com.xsqf.jt808.service.ILocationRecordService;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

/**
 * @Author:
 * @Date: 2020-5-14
 * @Description: 位置消息->CommonResp
 * @Version: 1.0
 */

@Slf4j
@Component
@ChannelHandler.Sharable
public class LocationMsgHandler extends BaseHandler<LocationMsg> {

    @Autowired
    private ILocationRecordService locationRecordService;

    @Autowired
    private ChannelManager channelManager;

    @Autowired
    @Qualifier("workerGroup")
    private NioEventLoopGroup workerGroup;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, LocationMsg msg) throws Exception {
        log.info("位置信息上报：" + msg.toString());

        CommonResp resp = locationMsg(msg, getSerialNumber(ctx.channel()));
        if (resp != null) {
            workerGroup.execute(() -> write(ctx, resp));//直接write是由businessGroup执行，换成workerGroup写可以少一些判断逻辑，略微提升性能
        } else {
            ctx.close(channelManager.get(msg.getHeader().getTerminalPhone()).newPromise());
        }
    }

    public CommonResp locationMsg(LocationMsg msg, short flowId) throws Exception {
        CommonResp resp = new CommonResp();
        resp.getHeader().setTerminalPhone(msg.getHeader().getTerminalPhone());
        resp.getHeader().setFlowId(flowId);
        resp.setReplyFlowId(msg.getHeader().getFlowId());
        resp.setReplyId(msg.getHeader().getMsgId());
        resp.setResult(CommonResp.FAILURE);

        //验证session信息
        Object isAuthenticated = redisTemplate.opsForHash()
                .get("KEY:" + msg.getHeader().getTerminalPhone(), "isAuthenticated");
        if (isAuthenticated != null) {
            LocationRecord locationRecord = parseFromLocationMsg(msg);
            locationRecordService.save(locationRecord);
//            Map map = new HashMap();
//            map.put("latitude",locationRecord.getLatitude());
//            map.put("longitude",locationRecord.getLongitude());
//
//            //此处因业务需求把每次获得的经纬度信息存入Redis中
//            redisTemplate.opsForHash().putAll("LOCATION:"+locationRecord.getTerminalId(),map);
//            Map<Object, Object> fenceMap = redisTemplate.opsForHash().entries("LOCATION:"+locationRecord.getTerminalId());
//            fenceMap.put("latitude",locationRecord.getLatitude());
//            fenceMap.put("longitude",locationRecord.getLongitude());
//            redisTemplate.opsForHash().putAll("LOCATION:"+locationRecord.getTerminalId(),fenceMap);

//            VehicleTerminalVo vehicleTerminalVo;
            if (Objects.requireNonNull(redisTemplate.hasKey("LOCATION:" + locationRecord.getTerminalId()))) {
                VehicleTerminalVo vehicleTerminalVo = vehicleTerminalVoRedisTemplate.opsForValue().get("LOCATION:" + locationRecord.getTerminalId());
                System.out.println(vehicleTerminalVo);
                vehicleTerminalVo.setLatitude(locationRecord.getLatitude());
                vehicleTerminalVo.setLongitude(locationRecord.getLongitude());
                redisTemplate.opsForValue().set("LOCATION:" + locationRecord.getTerminalId(), vehicleTerminalVo);

            }

            resp.setResult(CommonResp.SUCCESS);
            return resp;
        }
        return null;
    }


    public LocationRecord parseFromLocationMsg(LocationMsg msg) throws Exception {
        LocationRecord location = new LocationRecord();
        location.setTerminalId(msg.getHeader().getTerminalPhone());
        BeanUtils.copyProperties(msg, location);
        location.setDirection((int) msg.getDirection());
        location.setElevation((int) msg.getElevation());
        location.setSpeed((int) msg.getSpeed());
        String[] status = BitOperator.get32BitString(msg.getStatusField()).split("");

        //状态解析
        int acc = Integer.parseInt(status[0]);//0：ACC 关；1： ACC 开
        int loca = Integer.parseInt(status[1]);//0：未定位；1：定位
        int lati = Integer.parseInt(status[2]);//0：北纬；1：南纬
        int longi = Integer.parseInt(status[3]);//0：东经；1：西经
        int operation = Integer.parseInt(status[4]);//0：运营状态；1：停运状态
        int encrypt = Integer.parseInt(status[5]);//0：经纬度未经保密插件加密；1：经纬度已经保密插件加密
        location.setAccStatus(acc);
        location.setLocationStatus(loca);
        location.setLatiType(lati);
        location.setLongiType(longi);
        location.setOperationStatus(operation);
        location.setEncryptStatus(encrypt);
        location.setCollectTime(getDate(msg.getTime()));

        //解析报警标志详情见 jt808协议
//        String[] strings = BitOperator.get32BitString(location.getAlarm()).split("");

        Map<Object, Object> authMap = redisTemplate.opsForHash().entries("AUTH:" + msg.getHeader().getTerminalPhone());
        if (authMap.size() > 0) {
            Long vehicleId = Long.valueOf(authMap.get("vehicleId") + "");
            location.setVehicleId(vehicleId);
        }
        return location;
    }

    public static Date getDate(String time) throws Exception {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        return simpleDateFormat.parse(time);
    }

}
